﻿using Micro.Extensions.Cache.Serializer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using StackExchange.Redis;
using System.Linq;

namespace Micro.Extensions.Cache.Redis.Extensions
{
    public static class RedisExtensions
    {
        public static IServiceCollection AddRedis(this IServiceCollection services, IConfigurationSection section)
        {
            var connections = section["Redis"];
            var arr = connections.Split(',').ToList();
            var prefix = arr.FirstOrDefault(f => f.ToLower().StartsWith("prefix"));
            var splitPrefix = prefix?.Split('=');
            var keyPrefix = splitPrefix?.Length > 1 ? splitPrefix[1] : "";
            arr.Remove(prefix);


            var options = ConfigurationOptions.Parse(string.Join(",", arr));
            options.ConnectRetry = 3;
            options.Ssl = false;

            var strEndpoints = string.Empty;
            foreach (var item in options.EndPoints)
            {
                strEndpoints += $"{item},";
            }

            services.Configure<RedisConfig>(config =>
            {
                config.ConnectTimeout = options.ConnectTimeout;
                config.Prefix = keyPrefix;
                config.ConnectTimeout = options.ConnectTimeout;
                config.Password = options.Password;
                config.KeepAlive = options.KeepAlive;
                config.SyncTimeout = options.SyncTimeout;
                config.AsyncTimeout = options.AsyncTimeout;
                config.Endpoints = strEndpoints.TrimEnd(',');
            });

            var redisConfig = services.BuildServiceProvider().GetService<IOptions<RedisConfig>>().Value;
            var connectionMultiplexer = ConnectionMultiplexer.Connect(options.ToString());
            AddRedis(services, connectionMultiplexer);
            return services;
        }

        public static IServiceCollection AddRedis(this IServiceCollection services, IConnectionMultiplexer connectionMultiplexer)
        {


            services.TryAddSingleton(connectionMultiplexer);
            services.TryAddSingleton<ICachingSerializer, DefaultJsonSerializer>();
            services.TryAddSingleton<IRedisDatabaseProvider, RedisDatabaseProvider>();
            services.TryAddSingleton<ICacheClient, RedisClient>();
            return services;
        }
    }
}